可以发现,这道题目主要要解决的问题是如何从输入的密文中分出加密之前每行的字母(之后按照 V 形遍历输出明文即可)。

先想到找每一行的规律,但找不出来,于是想到用模拟的方法,按照要求先模拟一遍加密,模拟中记下每个位置对应在行数。

这一部分代码如下:

1
2
3
4
5
6
7
//用sum记录第j行的字符个数
for(int i=1;i<=n;){
for(int j=1;j<=h&&i<=n;j++,i++)
sum[j]++;
for(int j=h-1;j>=2&&i<=n;j--,i++)
sum[j]++;
}

接下来,把每一个字母放进每一行:

1
2
3
4
//q[]是一个字符型队列数组,用来记录每一行的字母
for(int i=1,j=1;i<=h;i++)
for(int k=1;k<=sum[i];k++,j++)
q[i].push(s[j]);

再模拟一遍,输出结果:

1
2
3
4
5
6
7
8
9
10
for(int i=1;i<=n;){
for(int j=1;j<=h&&i<=n;j++,i++){
cout<<q[j].front();
q[j].pop();
}
for(int j=h-1;j>=2&&i<=n;j--,i++){
cout<<q[j].front();
q[j].pop();
}
}

相信已经不需要代码了

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<bits/stdc++.h>
using namespace std;
queue<char>q[101];
int sum[101];
int main(){
int h;
string s;
cin>>h>>s;
int n=s.size();
s=" "+s;
for(int i=1;i<=n;){
for(int j=1;j<=h&&i<=n;j++,i++){
sum[j]++;
}
for(int j=h-1;j>=2&&i<=n;j--,i++){
sum[j]++;
}
}
for(int i=1,j=1;i<=h;i++){
for(int k=1;k<=sum[i];k++,j++){
q[i].push(s[j]);
}
}
for(int i=1;i<=n;){
for(int j=1;j<=h&&i<=n;j++,i++){
cout<<q[j].front();
q[j].pop();
}
for(int j=h-1;j>=2&&i<=n;j--,i++){
cout<<q[j].front();
q[j].pop();
}
}
return 0;
}